package com.test.demo.domain;


import com.test.demo.RobotSimulation;
import com.test.demo.util.GeometryTools;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.util.AffineTransformation;
import org.locationtech.jts.geom.util.GeometryEditor;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;

public abstract class Robot implements Serializable {
    public int x, y;
    public Integer width = 50, height = 50;
    public Color color;
    protected boolean isAlive;
    protected boolean isBuildings;
    public double speedX, speedY;
    public String name;
    protected Shape shape;

    public Robot() {
        this.isAlive = true;
        this.speedX = Math.random() * 4 - 2;  // 初始随机速度（-2到2）
        this.speedY = Math.random() * 4 - 2;
    }


    public boolean isAlive() {
        return isAlive;
    }

    public boolean isHunter() {
        return getName().equals("机器人");
    }

    public void die() {
        isAlive = false;
    }

    public Shape getShape() {
        return shape;
    }

    // 随机移动
    public void randomMove() {
        x += speedX;
        y += speedY;

        // 防止机器人超出边界，碰到边界时反弹
        if (x <= 0 || x >= RobotSimulation.width - width) speedX = -speedX;
        if (y <= 0 || y >= RobotSimulation.height - height) speedY = -speedY;
    }

    public void move(int x, int y) {
        this.x = x;
        this.y = y;

        // 防止机器人超出边界，碰到边界时反弹
        if (x <= 0 || x >= RobotSimulation.width - width) {
            this.x = RobotSimulation.width - width;
        }
        if (y <= 0 || y >= RobotSimulation.height - height) {
            this.y = RobotSimulation.height - height;
        }
    }

    // 判断两个机器人是否相克
    public boolean isBeatenBy(Robot other) {
        if (!this.isAlive() || !other.isAlive()) return false;

        // 判断相克关系
        switch (this.getName()) {
            case "金": // 金色
                return other.getName().equals("木"); // 木色
            case "木": // 木色
                return other.getName().equals("土"); // 土色
            case "土": // 土色
                return other.getName().equals("水"); // 水色
            case "水": // 水色
                return other.getName().equals("火"); // 火色
            case "火": // 火色
                return other.getName().equals("金"); // 金色
            default:
                return false;
        }
    }

    Geometry geometry;

    public void moveShape(Graphics2D g2d) {
        AffineTransform transform = g2d.getTransform();
        // 获取Shape对象的边界框
        Rectangle2D bounds = shape.getBounds2D();

        // 计算缩放比例
        double scaleX = width / bounds.getWidth();
        double scaleY = height / bounds.getHeight();

        // 先进行缩放
        transform.scale(scaleX, scaleY);

        // 再平移到指定位置
        transform.translate(x - bounds.getX(), y - bounds.getY());  // 计算目标位置，避免多次平移

        // 应用变换到Shape对象
        shape = transform.createTransformedShape(shape);


        AffineTransformation scaling = new AffineTransformation();
        scaling.translate(x - bounds.getX(), y - bounds.getY());
        scaling.scale(scaleX, scaleY);
        geometry.apply(scaling);
        if (getName().equals("机器人")) {
            //在shape周围 绘制光环
            drawGlow(g2d, shape);
        }

        g2d.setColor(getColor());
        if (isHunter()) {
            g2d.draw(getShape());
        } else {
            g2d.fill(getShape());
        }

    }

    Geometry halo;

    // 方法：在形状周围绘制光环
    private void drawGlow(Graphics2D g2d, Shape shape) {


        // 获取Shape的边界框（用于确定光环的位置和大小）
        Rectangle2D bounds = shape.getBounds2D();

        // 计算形状的中心点
        double shapeCenterX = bounds.getCenterX();
        double shapeCenterY = bounds.getCenterY();

        // 计算光环的半径（光环比形状边界稍大）
        double haloRadius = Math.max(bounds.getWidth(), bounds.getHeight()) * 2; // 比形状边界大 20%

        // 设置光环的透明度和颜色
        Color haloColor = new Color(234, 200, 255, 108); // 半透明黄色

        Ellipse2D ellipse2D = new Ellipse2D.Double((shapeCenterX - haloRadius / 2), (shapeCenterY - haloRadius / 2), haloRadius, haloRadius);
        if (halo == null) {
            halo = GeometryTools.shapeToGeometry(ellipse2D);
        }
        AffineTransformation scaling = new AffineTransformation();

        // 计算Ellipse2D的中心位置
        double ellipseCenterX = ellipse2D.getCenterX();
        double ellipseCenterY = ellipse2D.getCenterY();

        // 计算平移量
        double translateX = ellipseCenterX - halo.getCentroid().getX();
        double translateY = ellipseCenterY - halo.getCentroid().getY();

        scaling.translate(translateX, translateY);
        halo.apply(scaling);

        g2d.setColor(haloColor);
        g2d.fill(ellipse2D);
    }

    public Geometry getGeometry() {
        return geometry;
    }

    public Geometry getHalo() {
        return halo;
    }

    public void setSpeed(double speedX, double speedY) {
        this.speedX = speedX;
        this.speedY = speedY;
    }

    Color color1 = new Color(255, 153, 0); //金
    Color color2 = new Color(21, 156, 6); //木
    Color color3 = new Color(121, 96, 61); //土
    Color color4 = new Color(134, 134, 169); //水
    Color color5 = new Color(255, 0, 0); //火
    Color color6 = new Color(117, 117, 117); //火
    Color color7 = new Color(37, 128, 34); //火

    //根据名称获取颜色
    public Color getColorByName() {
        switch (name) {
            case "金":
                return color1;
            case "木":
                return color2;
            case "土":
                return color3;
            case "水":
                return color4;
            case "火":
                return color5;
            case "机器人":
                return color6;
            case "圣诞树":
                return color7;
            default:
                return null;
        }
    }


    public String getName() {
        return name;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public boolean isBuildings() {
        return isBuildings;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setHalo(Geometry halo) {
        this.halo = halo;
    }

    public void setGeometry(Geometry geometry) {
        this.geometry = geometry;
    }

    public void setShape(Shape shape) {
        this.shape = shape;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSpeedY() {
        return speedY;
    }

    public void setSpeedY(double speedY) {
        this.speedY = speedY;
    }

    public double getSpeedX() {
        return speedX;
    }

    public void setSpeedX(double speedX) {
        this.speedX = speedX;
    }

    public void setBuildings(boolean buildings) {
        isBuildings = buildings;
    }

    public void setAlive(boolean alive) {
        isAlive = alive;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public Color getColor() {
        return color;
    }
}
